/*****************************************************************************
*
*  @file     AdcDriver.c
*  @brief    ADC采样驱动
*            1. 负责实现ADC采样
*			 2. 负责实现为各个模块提供ADC采样原始值
*
*  @author   潘学林
*  @email                                        
*  @version  V0.000
*  @date     2022/4/11
*  @license  /
*----------------------------------------------------------------------------*
*  Remark         : Description                                              *
*----------------------------------------------------------------------------*
*  Change History :                                                          *
*  <Date>     | <Version> | <Author>       | <Description>                   *
*----------------------------------------------------------------------------*
*  2022/4/11  | 0.000     | 潘学林         | 创建文件                        *
*----------------------------------------------------------------------------*
*
*****************************************************************************/

/* Includes ------------------------------------------------------------------*/

#include "AdcDriver.h"   

/* Micros/Enumerate/Structures -----------------------------------------------*/

/* Variables -----------------------------------------------------------------*/

/* ADC采样控制信息 */
static ADC_SAMPLE_DRIVER_CTRL_INFO adcDriverCtrlInfo;

/* Functions -----------------------------------------------------------------*/

/*****************************************
* 内部函数
*****************************************/
/**
  * @brief  ADC采样参数初始化
  * @param  None
  * @retval None
  */
static void AdcDriver_ParameterInit(void)
{
	for (ADC_SAMPLE_TYPE i=AFE1_NTC4_AD; i<ADC_SAMPLE_TYPE_MAX; i++)
	{
		adcDriverCtrlInfo.adcSampleValue[i] = 0;
	}
}

/**
  * @brief  ADC时钟初始化
  * @param  None
  * @retval None
  */
static void AdcDriver_ClockInit(void)
{
	/* enable the GPIOA clock */
	rcu_periph_clock_enable(RCU_GPIOA);
	/* enable the GPIOB clock */
	rcu_periph_clock_enable(RCU_GPIOB);
	/* enable the GPIOC clock */
	rcu_periph_clock_enable(RCU_GPIOC);
	/* enable ADC0 clock */
	rcu_periph_clock_enable(RCU_ADC0);
	/* config ADC clock,120M/4=30M */
	rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV4);
	/* enable DMA0 clock */
	rcu_periph_clock_enable(RCU_DMA0);
	/* enable aiternate function clock */
	rcu_periph_clock_enable(RCU_AF);
}

/**
  * @brief  ADC引脚初始化
  * @param  None
  * @retval None
  */
static void AdcDriver_GpioInit(void)
{
	/* configure adc GPIO port */ 
	gpio_init(AFE1_NTC4_AD_Port, GPIO_MODE_AIN, GPIO_OSPEED_MAX, AFE1_NTC4_AD_Pin);
	gpio_init(AFE1_NTC5_AD_Port, GPIO_MODE_AIN, GPIO_OSPEED_MAX, AFE1_NTC5_AD_Pin);
	gpio_init(AFE1_NTC6_AD_Port, GPIO_MODE_AIN, GPIO_OSPEED_MAX, AFE1_NTC6_AD_Pin);
    
	gpio_init(AFE2_NTC4_AD_Port, GPIO_MODE_AIN, GPIO_OSPEED_MAX, AFE2_NTC4_AD_Pin);
	gpio_init(AFE2_NTC5_AD_Port, GPIO_MODE_AIN, GPIO_OSPEED_MAX, AFE2_NTC5_AD_Pin);
	gpio_init(AFE2_NTC6_AD_Port, GPIO_MODE_AIN, GPIO_OSPEED_MAX, AFE2_NTC6_AD_Pin);
    
	gpio_init(NTC1_AD_Port, GPIO_MODE_AIN, GPIO_OSPEED_MAX, NTC1_AD_Pin);
	gpio_init(PACK_ID_AD_Port, GPIO_MODE_AIN, GPIO_OSPEED_MAX, PACK_ID_AD_Pin);
    
	gpio_init(VB_72V_AD_Port, GPIO_MODE_AIN, GPIO_OSPEED_MAX, VB_72V_AD_Pin);
	gpio_init(VCC_3V3_PR_AD_Port, GPIO_MODE_AIN, GPIO_OSPEED_MAX, VCC_3V3_PR_AD_Pin);
	gpio_init(A_POSITIVE_AD_Port, GPIO_MODE_AIN, GPIO_OSPEED_MAX, A_POSITIVE_AD_Pin);
	gpio_init(CC2_AD_Port, GPIO_MODE_AIN, GPIO_OSPEED_MAX, CC2_AD_Pin);
}

/**
  * @brief  dma初始化
  * @param  None
  * @retval None
  */
static void AdcDriver_DmaInit(void)
{
	/* ADC_DMA_channel configuration */
	dma_parameter_struct dma_data_parameter;

	/* ADC DMA_channel configuration */
	dma_deinit(DMA0, DMA_CH0); 

	/* initialize DMA single data mode */
	dma_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(ADC0));
	dma_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
	dma_data_parameter.memory_addr = (uint32_t)(&adcDriverCtrlInfo.adcSampleValue);
	dma_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
	dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
	dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;  
	dma_data_parameter.direction = DMA_PERIPHERAL_TO_MEMORY;
	dma_data_parameter.number = ADC_SAMPLE_TYPE_MAX;
	dma_data_parameter.priority = DMA_PRIORITY_HIGH;
	dma_init(DMA0, DMA_CH0, &dma_data_parameter);

	/* enable DMA circulation mode */
	dma_circulation_enable(DMA0, DMA_CH0);

	/* enable DMA channel */
	dma_channel_enable(DMA0, DMA_CH0);
}

/**
  * @brief  adc初始化
  * @param  None
  * @retval None
  */
static void AdcDriver_AdcInit(void)
{
	/* reset ADC */
	adc_deinit(ADC0);
	/* ADC mode config */
	adc_mode_config(ADC_MODE_FREE);
	/* ADC continous function enable */
	adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE);
    /* ADC continous function enable */
	adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
    
	/* ADC data alignment config */
	adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
	
	/* ADC channel length config */
	adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, ADC_SAMPLE_TYPE_MAX);
	/* ADC regular channel config */
	adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_1, ADC_SAMPLETIME_239POINT5);
	adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_2, ADC_SAMPLETIME_239POINT5);
	adc_regular_channel_config(ADC0, 2, ADC_CHANNEL_3, ADC_SAMPLETIME_239POINT5);
	adc_regular_channel_config(ADC0, 3, ADC_CHANNEL_7, ADC_SAMPLETIME_239POINT5);
	adc_regular_channel_config(ADC0, 4, ADC_CHANNEL_8, ADC_SAMPLETIME_239POINT5);
	adc_regular_channel_config(ADC0, 5, ADC_CHANNEL_9, ADC_SAMPLETIME_239POINT5);
	adc_regular_channel_config(ADC0, 6, ADC_CHANNEL_4, ADC_SAMPLETIME_239POINT5);
	adc_regular_channel_config(ADC0, 7, ADC_CHANNEL_5, ADC_SAMPLETIME_239POINT5);
	adc_regular_channel_config(ADC0, 8, ADC_CHANNEL_10, ADC_SAMPLETIME_239POINT5);
	adc_regular_channel_config(ADC0, 9, ADC_CHANNEL_11, ADC_SAMPLETIME_239POINT5);
	adc_regular_channel_config(ADC0, 10, ADC_CHANNEL_14, ADC_SAMPLETIME_239POINT5);
	adc_regular_channel_config(ADC0, 11, ADC_CHANNEL_15, ADC_SAMPLETIME_239POINT5);
	
	/* ADC trigger config */
	adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
	adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
	/* ADC DMA function enable */
	adc_dma_mode_enable(ADC0);
	
	/* enable ADC interface */
	adc_enable(ADC0);
	/* delay */
	delay_1ms(2);
	/* ADC calibration and reset calibration */
	adc_calibration_enable(ADC0);
    
    /* trigger enable */
    adc_software_trigger_enable(ADC0,ADC_REGULAR_CHANNEL);
}

/*****************************************
* 接口函数
*****************************************/
/**
  * @brief  ADC初始化
  * @param  None
  * @retval None
  */
void AdcDriver_Init(void)
{
	/* 1. 参数初始化 */
	AdcDriver_ParameterInit(); 
	
	/* 2. ADC时钟初始化 */
	AdcDriver_ClockInit();
	
	/* 3. Gpio硬件初始化 */
	AdcDriver_GpioInit();

	/* 4. Dma初始化 */
	AdcDriver_DmaInit();
	
	/* 5. ADC初始化 */
	AdcDriver_AdcInit();
}

/**
  * @brief  轮询任务
  * @param  None
  * @retval None
  */
void AdcDriver_PollTask(void)
{
	/* nop */
}

/**
  * @brief  获取ADC原始采样结果
  * @param  type 类型，result 结果
  * @retval None
  */
void AdcDriver_GetAdcSampleValue(ADC_SAMPLE_TYPE type,uint16 *result)
{
	*result = adcDriverCtrlInfo.adcSampleValue[type];
}

/**
  * @brief  获取ADC采样结果缓冲区首地址
  * @param  None
  * @retval 缓冲区首地址
  */
uint16 *AdcDriver_GetAdcSampleBuffAddr(void)
{
	return &adcDriverCtrlInfo.adcSampleValue[AFE1_NTC4_AD];
}

/********************************* END OF FILE ********************************/
